local json=require "cjson.safe"
local posix=require "posix"

local dbcfg={
    cfgdir={    --配置文件目录
        "/etc/dbcfg.d","/etc/dbconn.config.d"
    },
    cwxx,cwdm='',0 ,
    use=function(self,cfgname,name) --初始化函数，
        name=name or ""
        self.cfgdata={}
        if not cfgname then return end
        for i,v in pairs(self.cfgdir) do
            local fn=v .. "/" .. cfgname .. ".cfg"
            local f=io.open(fn,"r")
            if f then
                local jg=f:read("*all")
                f:close()
                local data=json.decode(jg)
                for i,v in pairs(data) do
                    if name=="" or name==(v.name or "") then
                        self.cfgdata=v
                        return
                    end
                end
                return
            end
        end
    end,
    connect=function(self)  --连接到数据库
        self.dbdriver=require ("dbcfg_" .. self.cfgdata.db)
        self.db=self.dbdriver:new()
        self.db:connect()
    end,
    printdata=function(self)    --打印读入的数据
    end,
    cw=function(self,cwxx,cwdm)
        self.cwdm=cwdm or 0
        self.cwxx=cwxx or ""
        return cwdm
    end,
    dbinit=function(self,xh)    --根据序号初始化数据库连接，如果未指定序号则初始化所有
        ngx.ctx.db={}
        for i,v in pairs(self.localset.db or {}) do
            if ((not xh ) or xh==i ) and v.db and self["initdb_" .. v.db] then
                self["db".. i]=self["initdb_" .. v.db](self,v)
                ngx.ctx.db[i]=self["db".. i]
            end
        end
        self.db=self["db1"]
    end,
    init=function(self)
        local cjson2=self.cjson.new()
        self.posix=require "posix"
        self.json=require "cjson.safe"
        self.sd=ngx.shared.shared_data
        self:dbinit()
        return ngx.ctx.db[1]
--      return self.db
    end,
    initdb_mysql=function(self,conf)
        local mysql=require "resty.mysql"
        local db,err = mysql:new()
        if not db then
            self:rz("mysql lib init error")
            ngx.exec("@cw")
        end
        db:set_timeout(100000)
        local ok,err,errno,sqlstate = db:connect (conf.connect_conf)
        if not ok then
            self:rz({"mysql connect error:",err,errno,sqlstate})
            ngx.exec("@cw")
        end
        
        for i,v in pairs(conf.initsql or {}) do
            db:query(v)
        end
        return db
    end,
    initdb_oracle=function(self,conf)
        return ora:new(conf)
    end,
    initdb_mysql2=function(self,conf)
        return my:new(conf)
    end,
    quit=function(self,msg,...)
        if select("#",...)>0 then msg=string.format(msg, ...) end
        if msg and msg~="" then ngx.say(msg) end
        if self.db.set_keepalive then
            local ok,err=self.db:set_keepalive(10000,100)
        end
        ngx.exit(ngx.OK)
    end,
    rz=function(self,msg,...)   --输出日志信息
        if select("#",...)>0 then msg=string.format(msg, ...) end
        if type(msg)=="table" then msg=self.cjson.encode(msg) end
        local s=debug.getinfo(2)
        msg=s and string.format("%s:%s:%s",s.short_src,s.currentline,msg) or msg
        if self.rz2say then
            ngx.say(msg)
        else
            ngx.log(ngx.ERR,msg)
        end
    end,
    disparg=function(self) --显示所有get、post等参数
        ngx.req.read_body()
        local postargs = ngx.req.get_post_args()
        for k,v in pairs(postargs or {}) do
            if v==true then
                self:rz(self.json.decode(k))
                break
            end
            self:rz(k .. ":" .. v)
        end
    end,
    querys=function(self,sql,...)   --返回多个结果
        if select("#",...)>0 then
            local t={}
            for i,v in ipairs({...}) do
                if type(v)=="string" then
                    t[i]=ngx.quote_sql_str(v)
                else
                    t[i]=v
                end
            end
            sql=sql:format(unpack(t))
        end
        self.res,self.dberr,self.dberrno,self.sqlstate = self.db:query(sql)
        if not self.res then
            self:rz({sql,self.dberr,self.dberrno,self.sqlstate})
        end
        return self.res
    end,
    query=function(self,sql,...)    --如果是单一结果，返回结果集本身
        local res=self:querys(sql,...)
        if not res then return end
        if #res==0 then return end
        if #res==1 then
            return res[1]
        end
        return res
    end,
    s2num=function(self,...)
        local t={}
        for i,v in ipairs({...}) do
            t[i]=tonumber(v)
        end
        return unpack(t)
    end,
    togbk=function(self,utf8str)
        local iconv = require("iconv")
        local togbk = iconv.new("gbk","utf-8")
        local str, err = togbk:iconv(utf8str)
        return str
    end,
    toutf8=function(self,gbkstr)
        local iconv = require("iconv")
        local toutf8 = iconv.new("utf-8","gbk")
        local str, err = toutf8:iconv(gbkstr)
        return str
    end,
    new=function(self,cfgname)  --创建一个对象实例
        local o={}
        setmetatable(o,self)
        self.__index=self
        o:use(cfgname)
        return o
    end,
}

return dbcfg
